
import struct

from ip import IP_ADDR_SIZE
from ethernet import MAC_ADDR_SIZE, ETHERNET_TYPE_IP
from packet import Packet

ETHERNET_HW_TYPE = 0x0001
ARP_OPCODE_REQUEST = 0x0001

class ARP(Packet):
    def __init__(self, src_mac, src_ip, who_has_ip):
        Packet.__init__(self)
        
        # check packet arguments
        if (IP_ADDR_SIZE != len(src_ip)) or (MAC_ADDR_SIZE != len(src_mac)):
            raise Exception("Invalid IP or MAC address length")
        
        # set local members
        self.m_src_mac = src_mac
        self.m_src_ip = src_ip
        self.m_who_has_ip = who_has_ip
        
        # build headers
        self.m_header = struct.pack("!HH", ETHERNET_HW_TYPE, ETHERNET_TYPE_IP)
        self.m_header += struct.pack("!BBH", MAC_ADDR_SIZE, IP_ADDR_SIZE, ARP_OPCODE_REQUEST)
        self.m_header += self.m_src_mac + self.m_src_ip
        self.m_header += ("\0" * MAC_ADDR_SIZE) + self.m_who_has_ip